<?php
/* This script (re)creates the orm files required for Database.
 */
$myClasses = array();

//echo "Removing old PHP orms...\n";
removeOrms($ormDir);

//echo "Removing old Javascript classes...\n";
removeOrms($jsDbDir);

//echo "Reading attributes...\n";
readMyClasses($classesDir, 'readAttributes');

//echo "Reading variables...\n";
readMyClasses($classesDir, 'readVariables');

//echo "Writing orm files...\n";
writeOrms();

//echo "Writing Javascript classes...\n";
writeJsClasses();

//echo "Writing orm.inc.php...\n";
writeInc();

//echo "Writing _create.php...\n";
writeCreate();

echo "Done.\n";

function removeOrms($dir) {
  $dh = opendir($dir);
  if (!$dh) {
    echo "ERROR: Couldn't open directory: $dir\n";
    return;
  }
  while (($file = readdir($dh)) !== false) {
    $name = "$dir/$file";
    if (is_dir($name)) {
      continue;
    }
    unlink($name);
  }
  closedir($dh);
}

function readMyClasses($dir, $func) {
  global $ormDir;

  $dh = opendir($dir);
  if (!$dh) {
    echo "ERROR: Couldn't open directory: $dir\n";
    return;
  }
  while (($file = readdir($dh)) !== false) {
    if ($file[0] == '.') {
      continue;
    }
    $name = "$dir/$file";
    if (is_dir($name)) {
      if ($name != $ormDir) {
        echo " -> $name\n";
        readMyClasses($name, $func);
      }
      continue;
    } else {
      $fp = file_get_contents($name);
      if ($fp === false) {
        echo "ERROR: Failed to read: $name\n";
      } else {
        call_user_func($func, $name, $fp);
      }
    }
  }
  closedir($dh);
}

function readAttributes($file, $fp) {
  global $myClasses;
  $matches = array();
  if (preg_match_all('/orm (.*)/m', $fp, $matches)) {
    $myClasses[$file]['attr'] = $matches[1];
  }
}

function readVariables($file, $fp) {
  global $myClasses;
  $matches = array();
  if (preg_match_all('/public \$(.*);/m', $fp, $matches)) {
    $myClasses[$file]['var'] = $matches[1];
  }
}

function writeOrms() {
  global $myClasses;
  
  foreach ($myClasses as $name => &$class) {
    _writeOrm($name, $class['attr'], $class['var']);
  }
}

function _writeOrm($file, $attributes, $variables) {
  global $ormDir;
  
  $name = basename($file);
  $name = substr($name, 0, stripos($name, '.'));
  $file = "$ormDir/ORM$name.class.php";
  $fp = fopen($file, 'wt');
  if ($fp === false) {
    echo "ERROR: Failed to write: $file\n";
  } else {
    fprintf($fp, "<?php\n");
    fprintf($fp, "class ORM%s {\n", $name);
    fprintf($fp, "  public function toObj(\$args) {\n");
    fprintf($fp, "    \$obj = new stdClass();\n");
    _toObj($fp, $attributes, $variables);
    fprintf($fp, "    return \$obj;\n");
    fprintf($fp, "  }\n");
    fprintf($fp, "}\n");
    fprintf($fp, "?>\n");
    fclose($fp);
  }
}

function _toObj($fp, $attributes, $variables) {
  foreach ($attributes as $key => &$attribute) {
    $variable = $variables[$key];
    
    $variable = trim($variable);
    $attribute = trim($attribute);
    
    $contents = explode(' ', $attribute);
    $default = 0;
    if (stripos($contents[0], 'char') !== false || stripos($contents[0], 'clob') !== false || stripos($contents[0], 'blob') !== false) {
      $default = '\'\'';
    }
    fprintf($fp, "    if (isset(\$args->%s)) {\n      \$obj->%s =  \$args->%s;\n    }\n", $variable, $variable, $variable);
  }
}

function writeJsClasses() {
  global $myClasses;
  
  foreach ($myClasses as $name => &$class) {
    _writeJsClass($name, $class['attr'], $class['var']);
  }
}

function _writeJsClass($file, $attributes, $variables) {
  global $jsDbDir;
  $name = basename($file);
  $name = substr($name, 0, stripos($name, '.'));
  $file = "$jsDbDir/" . strtolower($name) . '.class.tpl';
  $fp = fopen($file, 'wt');
  if ($fp === false) {
    echo "ERROR: Failed to write: $file\n";
  } else {
    fprintf($fp, "function %s() {\n", $name);
    fprintf($fp, "};\n");
    fprintf($fp, "\n");
    fprintf($fp, "%s.instance = function() {\n", $name);
    foreach ($attributes as $key => &$attribute) {
      $variable = $variables[$key];
      $variable = trim($variable);
      $attribute = trim($attribute);
      $default = 'null';
      $contents = explode(' ', $attribute);
      if (stripos($contents[0], 'char') !== false || stripos($contents[0], 'text') !== false) {
          $default = '\'\'';
        } else if (stripos($contents[0], 'date') !== false) {
          $default = 'parseInt(new Date().getTime() / 1000, 10) ';
        } else {
          $default = 0;
        }
      if ($variable == 'track_id') {
        $default = 'MiscUtils.unique()';
      }
      if ($key == 0) {
        fprintf($fp, "  return { %s: %s%s\n", $variable, $default, ($key == (count($attributes) - 1)) ? '' : ',');
      } else {
        fprintf($fp, "           %s: %s%s\n", $variable, $default, ($key == (count($attributes) - 1)) ? '' : ',');
      }
    }
    fprintf($fp, "         }\n");
    fprintf($fp, "};\n");
    fclose($fp);
  }
}

function writeInc() {
  global $incFile, $myClasses;
  $fp = fopen($incFile, 'wt');
  if ($fp === false) {
    echo "ERROR: Failed to write: $incFile\n";
  } else {
    fprintf($fp, "<?php\n");
    fprintf($fp, "function classToOrm(\$class = NULL) {\n");
    fprintf($fp, "  \$class = strtolower(\$class);\n");
    fprintf($fp, "  switch (\$class) {\n");
    $files = array_keys($myClasses);
    sort($files);
    foreach ($files as &$file) {
      $name = basename($file);
      $name = substr($name, 0, stripos($name, '.'));
      fprintf($fp, "    case '%s':\n", strtolower($name));
      fprintf($fp, "      require_once dirname(__FILE__) . '/ORM%s.class.php';\n", $name);
      fprintf($fp, "      return new ORM%s();\n", $name);
    }
    fprintf($fp, "    default:\n");
    fprintf($fp, "      return NULL;\n");
    fprintf($fp, "  }\n");
    fprintf($fp, "  return NULL;\n");
    fprintf($fp, "}\n");
    fprintf($fp, "?>\n");
    fclose($fp);
  }
}

function writeCreate() {
  global $createFile, $myClasses;
  $fp = fopen($createFile, 'wt');
  if ($fp === false) {
    echo "ERROR: Failed to write: $createFile\n";
  } else {
    fprintf($fp, "<?php\n");
    fprintf($fp, "require_once dirname(__FILE__) . '/../common.inc.php';\n");
    fprintf($fp, "try {\n");
    fprintf($fp, "  \$hostname = DB_HOST;\n");
    fprintf($fp, "  \$username = DB_LOGIN;\n");
    fprintf($fp, "  \$password = DB_PASS;\n");
    fprintf($fp, "  \$dbname = DB_NAME;\n");
    fprintf($fp, "  \$myPdo = new PDO ('mysql:host=' . \$hostname, \$username, \$password);\n");
    fprintf($fp, "  \$myPdo->exec('USE ' . \$dbname);\n");
    fprintf($fp, "  \$myPdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n");
    foreach ($myClasses as $file => &$class) {
    	$name = basename($file);
      $name = substr($name, 0, stripos($name, '.'));
      fprintf($fp, "  \$sql = \"CREATE TABLE IF NOT EXISTS `%s`(\n", $name);
      fprintf($fp, "           `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,\n");
      foreach ($class['attr'] as $key => &$attribute) {
        $variable = $class['var'][$key];
        $variable = trim($variable);
        $attribute = trim($attribute);
        $seprator = ($key == (count($class['attr']) - 1)) ? '' : ',';
        fprintf($fp, "           `%s` %s%s\n", $variable, $attribute, $seprator);
      }
      fprintf($fp, "          ) ENGINE=MYISAM;\";\n");
      fprintf($fp, "  \$myPdo->exec(\$sql);\n");
    }
    fprintf($fp, "  echo 'Completed Successfully.';\n");
    fprintf($fp, "} catch (PDOException \$e) {\n");
    fprintf($fp, "  echo ERROR_SIGN . \$e->getMessage();\n");
    fprintf($fp, "}\n");
    fprintf($fp, "?>\n");
    fclose($fp);
  }
}
?>
